﻿#include "express.h"
#include "ui_express.h"

Express::Express(QWidget *parent) :
    BaseEditorDialog(parent),
    ui(new Ui::Express)
{
    ui->setupUi(this);

    table=TD_EXPRESS;
    noticeTable=TD_EXPRESS_NOTICE;

    _model=new QStandardItemModel(this);
    ui->tableView->setModel(_model);
    ui->tableView->setEditTriggers(QTableView::NoEditTriggers);

    enablePost=false;
    enableAne=false;
    ui->length->setEnabled(enablePost);
    ui->width->setEnabled(enablePost);
    ui->height->setEnabled(enablePost);

    getNotice();
    createMenu();
    loadLocation();
}

Express::~Express()
{
    saveLocation();
    delete ui;
}

void Express::generateMenu()
{
    menu->addAction(QStringLiteral("百世快运"),this,&Express::showBestFreight);
}

void Express::showBestFreight()
{
    BestFreight best;
    best.move(400,200);
    best.exec();
}

void Express::updateView(const QString &location, double dMass)
{
    int mass=qRound(dMass);
    if(mass < dMass)
        mass += 1;

    QSqlQuery query;
    query.exec(QString("select express,location from %1 where location like '%2%'")
               .arg(table)
               .arg(location));
    while (query.next()) {
        QString express=query.value("express").toString();
        QString location=query.value("location").toString();
        QSqlQuery query;
        QString sql=QString("select first,last,step from %1 where express='%2' AND location ='%3'")
                .arg(table)
                .arg(express)
                .arg(location);
        query.exec(sql);
        if(query.next())
        {
            double first=query.value("first").toDouble();
            double last=query.value("last").toDouble();
            int step=query.value("step").toInt();
            double total_price=0;
            QString summary;
            if(mass <= step)
            {
                total_price=first;
                summary=QString::number(step) + QStringLiteral("公斤内为起步价");
            }
            else
            {
                total_price=first + (mass - 1) * last;
                summary=QStringLiteral("首重(") + QString::number(first) + QString(")") +
                        QString(" + (") +
                        QString::number(mass) + QString(" - 1) * ") +
                        QStringLiteral("续重(") + QString::number(last) + QString(")");
            }

            QList<QStandardItem *> item;
            item.append(new QStandardItem(express));
            item.append(new QStandardItem(location));
            item.append(new QStandardItem(QString::number(total_price)));
            item.append(new QStandardItem(QString::number(total_price / 1000)));    //伪排序
            item.append(new QStandardItem(summary));
            _model->appendRow(item);
        }
        else
        {
            QList<QStandardItem *> item;
            item.append(new QStandardItem(express));
            item.append(new QStandardItem(QStringLiteral("找不到相应地址！")));
            _model->appendRow(item);
        }
    }
}

void Express::on_btn_calc_clicked()
{
    QString location=ui->location->text().trimmed();
    QString mass=ui->mass->text().trimmed();
    if(location.isEmpty() || mass.isEmpty())
        return;

    if(_model->rowCount() != 0)
        _model->clear();

    bool ok;
    double dMass=mass.toDouble(&ok);
    if(!ok)
    {
        QMessageBox::warning(this,QStringLiteral("无效输入"),
                             QStringLiteral("请输入正确的数字！"));
        return;
    }
    else
    {
        updateView(location,dMass);

        if(enablePost)
        {
            double length=ui->length->text().toDouble();
            double width=ui->width->text().toDouble();
            double height=ui->height->text().toDouble();
            double perimeter=length + width + height;

            if(perimeter >= 100)
            {
                double volume=length * width * height;
                processPostBubble(location,dMass,volume);
            }
            else
                processPostExpress(location,dMass);
        }

        if(enableAne)
            processAneExpress(location,dMass);
    }

    if(_model->rowCount() > 0)
    {
        setHeaderData();
        ui->lbl_display->setText(location + QString(" ") + ui->mass->text()
                                 + QStringLiteral(" 公斤"));

        _model->sort(3);
        _model->item(0,0)->setBackground(QBrush(QColor(0,0xCC,0)));
        _model->item(0,2)->setBackground(QBrush(QColor(0,0xCC,0)));
    }
    else
        ui->lbl_display->setText(QStringLiteral("找不到该地址！"));

    ui->mass->clear();
}

void Express::setHeaderData()
{
    _model->setHeaderData(0,Qt::Horizontal,QStringLiteral("快递"));
    _model->setHeaderData(1,Qt::Horizontal,QStringLiteral("地点"));
    ui->tableView->setColumnWidth(1,180);
    _model->setHeaderData(2,Qt::Horizontal,QStringLiteral("价格"));
    ui->tableView->hideColumn(3);   //伪排序
    _model->setHeaderData(4,Qt::Horizontal,QStringLiteral("计算过程"));
}

void Express::processPost(const QString &location, double mass, double extra)
{
    QString level;
    if(mass > 4)
        level="level_5";
    else if(mass > 3)
        level="level_4";
    else if(mass > 2)
        level="level_3";
    else if(mass > 1)
        level="level_2";
    else if(mass > 0.5)
        level="level_1";
    else
        level="level_0";

    QSqlQuery query;
    query.exec(QString("select %1 from %2 where location='%3'")
               .arg(level).arg(TD_POST).arg(location));
    if(query.next())
    {
        double total=query.value(level).toDouble();
        double total_price=total+extra;
        QString summmary=QStringLiteral("起步价(") + QString::number(total) + QString(") + ")
                + QStringLiteral("附加费(") + QString::number(extra) + QString(")");

        QList<QStandardItem *> item;
        item.append(new QStandardItem(QStringLiteral("邮政")));
        item.append(new QStandardItem(location));
        item.append(new QStandardItem(QString::number(total_price)));
        item.append(new QStandardItem(QString::number(total_price / 1000)));    //伪排序
        item.append(new QStandardItem(summmary));
        _model->appendRow(item);
    }
}

void Express::processAneExpress(const QString &location, double mass)
{
    QSqlQuery query;
    query.exec(QString("select location,first,last,step from %1 where location like '%2%'")
               .arg(TD_EXPRESS_ANE)
               .arg(location));
    if(query.next())
    {
        QString location=query.value("location").toString();
        double first=query.value("first").toDouble();
        double last=query.value("last").toDouble();
        int step=query.value("step").toInt();
        double total_price=0;
        QString summary;
        if( mass >= 70)
        {
            total_price=mass * last;
            summary=QString::number(mass) + QString(" * ") + QString::number(last) + QStringLiteral("，70公斤以上只算续重");
        }
        else if(mass <= step)
        {
            total_price=first;
            summary=QString::number(step) + QStringLiteral("公斤内为起步价");
        }
        else
        {
            total_price=first + (mass - step) * last;
            summary=QStringLiteral("首重(") + QString::number(first) + QString(")") +
                    QString(" + (") +
                    QString::number(mass) + QString(" - ") + QString::number(step)  + QString(") * ") +
                    QStringLiteral("续重(") + QString::number(last) + QString(")");
        }

        QList<QStandardItem *> item;
        item.append(new QStandardItem(QStringLiteral("安能")));
        item.append(new QStandardItem(location));
        item.append(new QStandardItem(QString::number(total_price)));
        item.append(new QStandardItem(QString::number(total_price / 1000)));    //伪排序
        item.append(new QStandardItem(summary));
        _model->appendRow(item);
    }
    else
    {
        QList<QStandardItem *> item;
        item.append(new QStandardItem(QStringLiteral("安能")));
        item.append(new QStandardItem(QStringLiteral("找不到相应地址！")));
        _model->appendRow(item);
    }
}

void Express::processPostOver(const QString &location, double mass, double extra)
{
    QSqlQuery query;
    query.exec(QString("select first,last,step from %1 where location='%2'")
               .arg(TD_POST_OVER).arg(location));
    if(query.next())
    {
        double first=query.value("first").toDouble();
        double last=query.value("last").toDouble();
        double step=query.value("step").toDouble();
        double total_price=first + (mass - step) * last + extra;
        QString summary=QStringLiteral("首重(") + QString::number(first) + QString(")")
                + QString(" + (") + QString::number(mass)
                + QString(" - ") + QString::number(step) + QString(") * ")
                + QStringLiteral("续重(") + QString::number(last) + QString(") + ")
                + QStringLiteral("附加费(") + QString::number(extra) + QString(")");

        QList<QStandardItem *> item;
        item.append(new QStandardItem(QStringLiteral("邮政")));
        item.append(new QStandardItem(location));
        item.append(new QStandardItem(QString::number(total_price)));
        item.append(new QStandardItem(QString::number(total_price / 1000)));    //伪排序
        item.append(new QStandardItem(summary));
        _model->appendRow(item);
    }
}

void Express::processPostBubble(const QString &location, double mass, double volume)
{
    QSqlQuery query;
    query.exec(QString("select location,bubble from %1 where location like '%2%'")
               .arg(TD_POST).arg(location));
    if(query.next())
    {
        QString location=query.value("location").toString();
        bool ok;
        int bubble=query.value("bubble").toInt(&ok);
        if(!ok)
        {
            QList<QStandardItem *> item;
            item.append(new QStandardItem(QStringLiteral("邮政")));
            item.append(new QStandardItem(location));
            item.append(new QStandardItem("0"));
            item.append(new QStandardItem("1000"));   //伪排序
            item.append(new QStandardItem(QStringLiteral("计泡比例异常！")));
            _model->appendRow(item);
        }
        else
        {
            double weight=volume / bubble;  //计泡计算
            double value=qMax(weight,mass);     //计泡比较
            processPostExpress(location,value);
        }
    }
    else
    {
        QList<QStandardItem *> item;
        item.append(new QStandardItem(QStringLiteral("邮政")));
        item.append(new QStandardItem(QStringLiteral("找不到相应地址！")));
        _model->appendRow(item);
    }
}

void Express::processPostExpress(const QString &location, double mass)
{
    QSqlQuery query;
    query.exec(QString("select location,extra from %1 where location like '%2%'")
               .arg(TD_POST).arg(location));
    if(query.next())
    {
        QString location=query.value("location").toString();
        double extra=query.value("extra").toDouble();
        if(mass > 5)
            processPostOver(location,mass,extra);
        else
            processPost(location,mass,extra);
    }
    else
    {
        QList<QStandardItem *> item;
        item.append(new QStandardItem(QStringLiteral("邮政")));
        item.append(new QStandardItem(QStringLiteral("找不到相应地址！")));
        _model->appendRow(item);
    }
}

void Express::getNotice()
{
    QSqlQuery query;
    query.exec(QString("select label,detail from %1").arg(noticeTable));
    if(query.next())
    {
        QString label=query.value("label").toString();
        QString detail=query.value("detail").toString();
        ui->g_Notice->setTitle(label);
        ui->detail->setPlainText(detail);
    }
    else
        ui->g_Notice->setTitle(QStringLiteral("当前无通知"));
}

void Express::on_check_post_stateChanged(int state)
{
    if(state == Qt::Checked)
    {
        enablePost=true;
        ui->length->setEnabled(enablePost);
        ui->width->setEnabled(enablePost);
        ui->height->setEnabled(enablePost);
    }
    else
    {
        enablePost=false;
        ui->length->setEnabled(enablePost);
        ui->width->setEnabled(enablePost);
        ui->height->setEnabled(enablePost);

        ui->length->clear();
        ui->width->clear();
        ui->height->clear();
    }
}

void Express::on_check_ane_stateChanged(int state)
{
    if(state == Qt::Checked)
        enableAne=true;
    else
        enableAne=false;
}
